package com.example.springcloud.order.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.example.springcloud.order.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Sentinel 限流降级演示控制器
 *
 * 功能：
 * 1. QPS 限流演示
 * 2. 热点参数限流演示
 * 3. 熔断降级演示
 */
@Slf4j
@RestController
@RequestMapping("/sentinel")
public class SentinelController {

    private final AtomicInteger counter = new AtomicInteger(0);

    /**
     * QPS 限流演示
     *
     * 配置方式（在 Sentinel 控制台）：
     * 1. 访问 http://localhost:8858
     * 2. 登录：sentinel/sentinel
     * 3. 选择 order-service
     * 4. 簇点链路 -> testQpsLimit
     * 5. 流控规则 -> 新增流控规则
     *    - 资源名：testQpsLimit
     *    - 阈值类型：QPS
     *    - 单机阈值：2
     */
    @GetMapping("/qps")
    @SentinelResource(
        value = "testQpsLimit",
        blockHandler = "handleQpsBlock"
    )
    public Result<String> testQpsLimit() {
        int count = counter.incrementAndGet();
        log.info("QPS 限流测试，请求次数: {}", count);
        return Result.success("请求成功", "这是第 " + count + " 次请求");
    }

    /**
     * 热点参数限流演示
     */
    @GetMapping("/hotparam")
    @SentinelResource(
        value = "testHotParam",
        blockHandler = "handleHotParamBlock"
    )
    public Result<String> testHotParam(@RequestParam("userId") String userId) {
        log.info("热点参数限流测试，用户: {}", userId);
        return Result.success("请求成功", "用户 " + userId + " 访问成功");
    }

    /**
     * 慢调用比例熔断演示
     */
    @GetMapping("/slowcall")
    @SentinelResource(
        value = "testSlowCall",
        blockHandler = "handleSlowCallBlock"
    )
    public Result<String> testSlowCall(@RequestParam(value = "delay", defaultValue = "100") int delay) {
        log.info("慢调用熔断测试，延迟: {}ms", delay);
        try {
            Thread.sleep(delay);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return Result.success("请求成功", "延迟 " + delay + "ms 后响应");
    }

    // ==================== Block Handlers ====================

    public Result<String> handleQpsBlock(BlockException ex) {
        log.warn("QPS 限流触发: {}", ex.getRule());
        return Result.error(429, "请求过于频繁，请稍后重试");
    }

    public Result<String> handleHotParamBlock(String userId, BlockException ex) {
        log.warn("热点参数限流触发，用户: {}", userId, ex.getRule());
        return Result.error(429, "用户 " + userId + " 访问过于频繁，请稍后重试");
    }

    public Result<String> handleSlowCallBlock(int delay, BlockException ex) {
        log.warn("慢调用熔断触发: {}", ex.getRule());
        return Result.error(503, "服务熔断中，请稍后重试");
    }

    @PostMapping("/reset")
    public Result<String> reset() {
        counter.set(0);
        return Result.success("计数器已重置");
    }

    @GetMapping("/health")
    public Result<String> health() {
        return Result.success("Sentinel 演示服务运行正常");
    }
}

